package common;

import java.util.ArrayList;
import java.util.Stack;

public class Strings {

    public static String trimAndDelDoubleSpace(String str) {
        str = str.trim();
        while (str.contains("  "))
            str = str.replaceAll("  ", " ");
        return str;
    }

    public static String replaceAll(String str, String from1, String to1) {
        while (str.contains(from1))
            str = str.replaceAll(from1, to1);
        return str;
    }

    public static String replaceAll(String str, String from1, String to1, String from2, String to2) {
        while (str.contains(from1))
            str = str.replaceAll(from1, to1);
        while (str.contains(from2))
            str = str.replaceAll(from1, to2);
        return str;
    }

    public static int getSpaceShift(String str) {
        int shift = 0;
        while (str.length() > shift && str.charAt(shift) == ' ')
            shift++;
        return shift;
    }

    public static String getSpaceShift(int shift) {
        String str = "";
        for (int i = 0; i < shift; i++)
            str += " ";
        return str;
    }

    // Строка которую надо резделить
    // Строка являющася резделителем
    // разбить только по первому вхождению (т.е. на выходе либо вся строка, либо две, разделенные первым вхождением Разделителя)
    // учитывать скобки
    public static ArrayList<String> split(int lineNum, String str, String splitter, boolean firstOnly, boolean blocksInside) {
        ArrayList<String> strs = new ArrayList<String>();

        if (str.length() > 0 && splitter.length() > 0) {
            int quote = 0;                                  // для 0:   1: `  2: '  3: "
            Stack<Integer> blocks = new Stack<Integer>();   // для 0:   1: (  2: {  3: [

            int matchStart = -1;
            int matchShift = 0;
            int previousMatchEnd = 0;

            for (int i = 0; i < str.length(); i++) {
                if (firstOnly && strs.size() >= 1)
                    continue;
                char ch = str.charAt(i);

                if (quote == 0 && (ch == '`' || ch == '\'' || ch == '"')) {
                    if (ch == '`')
                        quote = 1;
                    else if (ch == '\'')
                        quote = 2;
                    else
                        quote = 3;
                    matchStart = -1;
                    continue;
                }
                if (quote != 0) {
                    if (ch == '`' && quote == 1 || ch == '\'' && quote == 2 || ch == '"' && quote == 3)
                        quote = 0;
                    matchStart = -1;
                    continue;
                }
                if (blocksInside) {
                    if (ch == '(' || ch == '{' || ch == '[') {
                        if (ch == '(')
                            blocks.push(1);
                        else if (ch == '{')
                            blocks.push(2);
                        else
                            blocks.push(3);
                        matchStart = -1;
                        continue;
                    }
                    if (ch == ')' || ch == '}' || ch == ']') {
                        if (blocks.size() == 0)
                            ;/*throw new ParseException("В строке '" + str + "' закрывающая скобка раньше открывающей " + ((lineNum >= 0) ? "(Срока " + lineNum + ")" : ""));*/
                        if (ch == ')') {
                            if (blocks.lastElement() == 1)
                                blocks.pop();
                            else
                                ;/*throw new ParseException("В строке '" + str + "' непарные скобки" + ((lineNum >= 0) ? "(Срока " + lineNum + ")" : ""));*/
                        } else if (ch == '}') {
                            if (blocks.lastElement() == 2)
                                blocks.pop();
                            else
                                ;/*throw new ParseException("В строке '" + str + "' непарные скобки (Срока " + lineNum + ")" + ((lineNum >= 0) ? "(Срока " + lineNum + ")" : ""));*/
                        } else if (ch == ']') {
                            if (blocks.lastElement() == 3)
                                blocks.pop();
                            else
                                ;/*throw new ParseException("В строке '" + str + "' непарные скобки (Срока " + lineNum + ")" + ((lineNum >= 0) ? "(Срока " + lineNum + ")" : ""));*/
                        }
                        matchStart = -1;
                        continue;
                    }
                }
                if (quote == 0 && blocks.size() == 0) {
                    // Тут мы оказываемся если не окружены символами ` ' " ( ) { } [ ]
                    if (matchStart == -1 && ch == splitter.charAt(0) || matchStart >= 0 && ch == splitter.charAt(matchShift)) {
                        if (matchStart == -1) {
                            matchStart = i;
                            matchShift = 1;
                        } else {
                            matchShift++;
                        }
                        if (matchShift == splitter.length()) {
                            strs.add(str.substring(previousMatchEnd, matchStart));
                            previousMatchEnd = matchStart + matchShift;
                            matchStart = -1;
                        }
                    } else
                        matchStart = -1;
                }
            }
            strs.add(str.substring(previousMatchEnd));
        } else
            strs.add(str);


        return strs;
    }
}
